﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;
using MindBreakerResources;

namespace MindBreaker
{
    class TextureManager
    {
       
        /**************************/
        /** SINGLETON MANAGEMENT **/
        /**************************/
        private static TextureManager instance;

        private TextureManager(Game game)
        {
            Console.WriteLine("Création du TextureManager");
            this._game = game;
            this._textures = new Dictionary<string, Texture2D>();
            this._loadedSprites = new Stack<string>();
        }

        public static TextureManager getInstance(Game game) {
            if (instance == null)
                instance = new TextureManager(game);
            return instance;
        }

        public static void destroyInstance()
        {
            if (instance != null) {
                instance._textures.Clear();
                instance = null;
            }
        }

        /****************/
        /** ATTRIBUTES **/
        /****************/

        public static float SOUND_VOLUME_MUSIC = 0.2f;
        public static float SOUND_VOLUME_EFFECT = 0.4f;

        private Dictionary<String, Texture2D> _textures;
        private Stack<String> _loadedSprites;
        private Game _game;

        /*****************/
        /** CONSTRUCTOR **/
        /*****************/
        
        public Texture2D getTexture(String textureKey)
        {
            if (this._textures.ContainsKey(textureKey))
            {
                Console.WriteLine("Utilisation de la texture " + textureKey + " en cache");
                // Si la texture a déjà été chargé, elle est directement retournée
                return this._textures[textureKey];
            }
            // Sinon elle est chargée, mise en cache et retournée
            Console.WriteLine("Chargement de la texture " + textureKey + " en cache");
            Texture2D texture = this.loadTexture(textureKey);
            this._textures.Add(textureKey, texture);
            return this.loadTexture(textureKey);
        }

        private Texture2D loadTexture(String textureKey) {
            return this._game.Content.Load<Texture2D>(textureKey);
        }

        public void loadSprites(String fileUrl)
        {

            Console.WriteLine("Chargement des sprites '" + fileUrl + "' ...");
            if (!this.LoadedSprites.Contains(fileUrl))
            {
                List<SpriteElementXml> spriteDatas = this._game.Content.Load<List<SpriteElementXml>>(fileUrl + "_info");
                Texture2D mainSprite = this._game.Content.Load<Texture2D>(fileUrl + "_data");
                // Instanciate vars
                Rectangle rectInfo; Texture2D cropTexture; Color[] data; int countSprite = 0;
                foreach (SpriteElementXml element in spriteDatas)
                {
                    // Chargement en cache des textures
                    Console.WriteLine("Chargement du sprite #" + element.key + " (" + element.width + "x" + element.height + ")");
                    rectInfo = new Rectangle(element.spriteX, element.spriteY, element.width, element.height);
                    cropTexture = new Texture2D(mainSprite.GraphicsDevice, rectInfo.Width, rectInfo.Height);
                    data = new Color[rectInfo.Width * rectInfo.Height];
                    mainSprite.GetData(0, rectInfo, data, 0, data.Length);
                    cropTexture.SetData(data);
                    this._textures.Add(element.key, cropTexture);
                    countSprite++;
                }
                Console.WriteLine(countSprite + " textures chargées !");
                this.LoadedSprites.Push(fileUrl);
            }
        }

        public Stack<String> LoadedSprites
        {
            get { return _loadedSprites; }
            set { _loadedSprites = value; }
        }
        
    }
}
